package com.xujie.domain.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xujie.domain.service.WeatherStatsService;
import com.xujie.infra.entity.WeatherRecords;
import com.xujie.infra.entity.WeatherStats;
import com.xujie.infra.mapper.WeatherRecordsMapper;
import com.xujie.infra.mapper.WeatherStatsMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class WeatherStatsServiceImpl implements WeatherStatsService {

  @Autowired
  private WeatherStatsMapper weatherStatsMapper;

  @Autowired
  private WeatherRecordsMapper weatherRecordsMapper;

  @Override
  public List<WeatherStats> getWeatherStats(String city, Date startDate, Date endDate) {
    LambdaQueryWrapper<WeatherStats> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.eq(WeatherStats::getCity, city)
        .ge(WeatherStats::getDataDate, startDate)
        .le(WeatherStats::getDataDate, endDate)
        .orderByAsc(WeatherStats::getDataDate);

    return weatherStatsMapper.selectList(queryWrapper);
  }

  @Override
  @Transactional(rollbackFor = Exception.class)
  public void calculateAndSaveStats(String city, Date date) {
    // 获取指定日期的天气记录
    LambdaQueryWrapper<WeatherRecords> recordsQuery = new LambdaQueryWrapper<>();
    recordsQuery.eq(WeatherRecords::getCity, city)
        .ge(WeatherRecords::getDataDate, getStartOfDay(date))
        .lt(WeatherRecords::getDataDate, getEndOfDay(date));

    List<WeatherRecords> records = weatherRecordsMapper.selectList(recordsQuery);

    if (records.isEmpty()) {
      log.info("No weather records found for city {} on date {}", city, date);
      return;
    }

    // 计算统计数据
    DoubleSummaryStatistics precipStats = records.stream()
        .map(WeatherRecords::getPrecipitation)
        .filter(Objects::nonNull)
        .mapToDouble(Double::doubleValue)
        .summaryStatistics();

    DoubleSummaryStatistics windStats = records.stream()
        .map(WeatherRecords::getWindSpeed)
        .filter(Objects::nonNull)
        .mapToDouble(Double::doubleValue)
        .summaryStatistics();

    // 构建统计实体
    WeatherStats stats = WeatherStats.builder()
        .city(city)
        .dataDate(date)
        .totalPrecipitation(precipStats.getSum())
        .avgPrecipitation(precipStats.getAverage())
        .maxPrecipitation(precipStats.getMax())
        .avgWindSpeed(windStats.getAverage())
        .maxWindSpeed(windStats.getMax())
        .recordCount((int) precipStats.getCount())
        .build();

    // 删除已有的统计数据
    LambdaQueryWrapper<WeatherStats> deleteWrapper = new LambdaQueryWrapper<>();
    deleteWrapper.eq(WeatherStats::getCity, city)
        .eq(WeatherStats::getDataDate, date);
    weatherStatsMapper.delete(deleteWrapper);

    // 保存新的统计数据
    weatherStatsMapper.insert(stats);
    log.info("Weather stats calculated and saved for city {} on date {}", city, date);
  }

  private Date getStartOfDay(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);
    return calendar.getTime();
  }

  private Date getEndOfDay(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.set(Calendar.HOUR_OF_DAY, 23);
    calendar.set(Calendar.MINUTE, 59);
    calendar.set(Calendar.SECOND, 59);
    calendar.set(Calendar.MILLISECOND, 999);
    return calendar.getTime();
  }
}